﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Xml.Linq;
using Newtonsoft.Json;
using Orchard.ContentManagement;
using Orchard.Recipes.Models;
using Orchard.Services;
using Wng.Deployment.Models;
using Wng.Deployment.Services;

namespace Wng.Deployment.DeploymentTargets {
    public class OrchardDeploymentTarget : IDeploymentTarget, IDeploymentTargetProvider {
        private readonly IContentManager _contentManager;
        private readonly ISigningService _signingService;
        private RemoteOrchardDeploymentPart _deploymentPart { get; set; }
        private Lazy<RemoteOrchardApiClient> _client { get; set; }
        private readonly IClock _clock;

        public OrchardDeploymentTarget(IContentManager contentManager, ISigningService signingService, IClock clock) {
            _contentManager = contentManager;
            _signingService = signingService;
            _clock = clock;
        }

        public DeploymentTargetMatch Match(IContent targetConfiguration) {
            if (targetConfiguration.Is<RemoteOrchardDeploymentPart>()) {
                _deploymentPart = targetConfiguration.As<RemoteOrchardDeploymentPart>();
                _client = new Lazy<RemoteOrchardApiClient>(() => new RemoteOrchardApiClient(_deploymentPart, _signingService, _clock));
                return new DeploymentTargetMatch { DeploymentTarget = this, Priority = 0 };
            }
            return null;
        }

        public void PushRecipe(string executionId, string recipeText) {
            var actionUrl = string.Format("import/recipe?executionId={0}", executionId);
            _client.Value.Post(actionUrl, recipeText);
        }

        public RecipeStatus GetRecipeDeploymentStatus(string executionId) {
            var actionUrl = string.Format("import/recipejournal?executionId={0}", executionId);
            var journal = _client.Value.Get(actionUrl);
            var element = XElement.Parse(journal);
            RecipeStatus status;
            if (element.Element("Status") == null || !Enum.TryParse(element.Element("Status").Value, out status)) {
                status = RecipeStatus.Unknown;
            }
            return status;
        }

        public void PushContent(IContent content) {
            var actionUrl = "import/content";
            var exportedItem = _contentManager.Export(content.ContentItem);
            _client.Value.Post(actionUrl, exportedItem.ToString());
        }
    }
}